//
// Created by yunnan xu on 2020/12/8.
//

#ifndef ANDROIDGRAPHICSDEMOS_RIGIDBODY_H
#define ANDROIDGRAPHICSDEMOS_RIGIDBODY_H

#include "ext.hpp"
#include "Convex.h"
#include <memory>

class Model;

namespace Phy {

    class RigidBody {
    public:

        RigidBody() = default;
        RigidBody(float m, glm::mat3x3 _IBody, const std::shared_ptr<Convex> & convex, std::shared_ptr<Model> model);
        void SetV(glm::vec3 lv);
        void SetW(glm::vec3 av);
        void SetForce(glm::vec3 f);
        void SetTorque(glm::vec3 t);
        glm::vec3 GetV() const;
        glm::vec3 GetW() const;

        void AddImpulseAt(glm::vec3 position, glm::vec3 impulse);

        std::shared_ptr<Convex> convex;
        void Update(double elapsed_time);

        glm::mat4 GetTranslationMat();
        glm::mat4 GetRotateMat();
        glm::mat4 GetScaleMat() const;

        void SetTranslationMat(glm::mat4 mat);
        void SetRotateMat(glm::mat4 mat);
        void SetScaleMat(glm::mat4 mat);

        glm::mat3x3 StarMat(glm::vec3);

        void SetMass(float m);
        void SetStatic();

        std::shared_ptr<Model> GetModel();

    private:

        // 刚体的属性
        float mass;                 // 刚体的质量
        glm::mat3x3 IBody;          // 刚体的初始惯性张量
        glm::mat3x3 IBodyInv;       // 刚体的初始惯性张量的逆矩阵

        // 刚体当前的状态
        glm::vec3 center;       // 质心当前的世界坐标
        glm::mat3x3 R;          // 刚体当前的旋转矩阵
        glm::vec3 P;            // 刚体的线性动量
        glm::vec3 L;            // 刚体的角动量

        glm::quat quaternion;   // 旋转的四元数

        glm::mat3x3 Iinv;       //  刚体当前的惯性张量的逆矩阵
        glm::vec3 v;            // 刚体的线速度
        glm::vec3 w;            // 刚体的角速度

        glm::vec3 force;        // 刚体当前受到的合力
        glm::vec3 torque;       // 刚体当前受到的合力矩

        glm::mat4x4 scale_mat;

        bool is_static;

        std::shared_ptr<Model> model_ptr;
    };

}

#endif //ANDROIDGRAPHICSDEMOS_RIGIDBODY_H
